<template>
	<div class="padding-lr-xs">
		<a-form v-if="!~['bpmn:CallActivity', 'bpmn:SubProcess'].indexOf(formData.type)">
			<a-divider><span class="text-bold">操作按钮</span></a-divider>
			<a-form-item label="" v-if="formData.type == 'bpmn:UserTask'">
				<s-table
				  ref="table"
				  :columns="columns"
				  :data="loadData"
				  rowKey="uuid"
				>
				  <span slot="buttonName" slot-scope="text, record">
						{{text}}
						<a-tooltip v-if="text == '驳回'">
							<template slot="title">
								若审批人驳回，则审批退回上一节点或指定节点。选择驳回后需要重新指定一条驳回路线并设置分支条件${outcome == '驳回'}
							</template>
							<a-icon type="question-circle" />
						</a-tooltip>
            <a-tooltip v-if="text == '前加签'">
							<template slot="title">
								任务在A这里，A这个时候需要BCD核对一下，等BCD核对之后又回到A这里
							</template>
							<a-icon type="question-circle" />
						</a-tooltip>
            <a-tooltip v-if="text == '后加签'">
							<template slot="title">
								任务在A这里，A这个时候需要BCD处理这个事情，处理完毕之后就不用管了，继续后面的审批环节
							</template>
							<a-icon type="question-circle" />
						</a-tooltip>
                <a-tooltip v-if="text == '委派'">
							<template slot="title">
								A由于某些原因不能处理该任务，可以把任务委派给用户B代理，当B处理完成之后再次回到用户A这里，在这个过程中A是任务的所有者，B是该任务的办理人
							</template>
							<a-icon type="question-circle" />
						</a-tooltip>
            <a-tooltip v-if="text == '转办'">
							<template slot="title">
								将任务转出，由办理人转让给指定人员，这时任务的原办理人不再拥有权限查看和办理
							</template>
							<a-icon type="question-circle" />
						</a-tooltip>
				  </span>
					<span slot="batchApproval" slot-scope="text, record">
						<a-checkbox v-if="record.buttonName == '同意' || record.buttonName == '驳回'" />
					</span>
					<span slot="enable" slot-scope="text, record">
						<a-switch size="small" :checked="record.enable?true:false" @change="switchChange($event, record, 'enable')" />
					</span>
					<span
            slot="dialogConfig"
            slot-scope="text, record"
            style="display: flex; align-items: center"
          >
            <a-switch
              size="small"
              :checked="record.dialog.enable ? true : false"
              :disabled="!record.enable"
              @change="switchDialogEnableChange($event, record, 'dialogConfig')"
            />
            <a-icon
              v-if="record.dialog.enable == true"
              type="setting"
              style="margin-left: 10px"
              @click="openBtnConfigDialog(record)"
            />
          </span>
				</s-table>
			</a-form-item>
		</a-form>
		<!-- 按钮弹窗配置 -->
    <button-dialog-config
      ref="buttonDialogConfigRef"
      @cancel="btnConfigDialogHandleCancel"
      @ok="btnConfigDialogHandleOk"
    />
	</div>
</template>

<script>
	import { STable } from "@/components";
	import buttonPopup from './modal/buttonModal.vue';
	import ButtonDialogConfig from "./modal/buttonDialogConfig";
	export default {
		name: "ButtonSetting",
		components: {
			STable,
			buttonPopup,
			ButtonDialogConfig,
		},
		data() {
			return {
				type: 0,
				btnPopups: false,
				columns: [{
					title: "操作按钮",
					dataIndex: "buttonName",
					align: "left",
					scopedSlots: { customRender: 'buttonName' }
				},
				{
					title: "标识",
					dataIndex: "buttonCode",
					align: "left"
					// width: 130
				},
				// {
				// 	title: "批量审批",
				// 	dataIndex: "batchApproval",
				// 	align: "center",
				// 	width: 80,
				// 	scopedSlots: { customRender: 'batchApproval' }
				// },
				{
          title: "是否弹窗",
          dataIndex: "dialog",
          align: "left",
          scopedSlots: { customRender: "dialogConfig" },
        },
				{
					title: "启用",
					dataIndex: "enable",
					align: "center",
					width: 70,
					scopedSlots: { customRender: 'enable' }
				}],
				loadData: (parameter) => {
				  const requestParameters = Object.assign({}, parameter);
				  return this.$post(
				    "/workflow/flowButton/getPageSet",
				    requestParameters
				  ).then((res) => {
						res.rows.forEach(item => {
							item.enable = false
							item.dialog = { enable: false, pageUrl: "" };
						})
						this.buttonCodeList.forEach(item => {
							let index = res.rows.map(e => e.buttonCode).indexOf(item);
							if(index != -1){
								res.rows[index].enable = true
								res.rows[index].dialog = this.dialogEnableList.find((e) => {
                if (e.nodeButtonCode === item) {
                  if (typeof e.dialog !== "undefined") {
                    return e.dialog;
                  } else {
                    return {
                      enable: false,
                      pageUrl: "",
                    };
                  }
                }
              }).dialog;
							}
						})
				    return res;
				  });
				},
				btnGroup: []
			}
		},
		props: {
			modeler: {
				type: Object,
				required: true
			},
			nodeElement: {
				type: Object,
				required: true
			},
			formData: {
				type: Object,
				required: true
			}
		},
		watch: {
			// 默认给每个任务节点选中同意按钮
			btnGroup: {
				deep: true,
				immediate: true,
				handler(newVal, oldVal) {
					if (newVal.length !== 0) {
						this.updateProperties({
							btnGroup: JSON.stringify(this.btnGroup)
						});
					}
				}
			},
			nodeElement: {
				deep: true,
				immediate: true,
				handler(newVal, oldVal) {
					this.executionListener = []
					this.taskListener = []
					const bpmnModeler = this.modeler
					const modeling = bpmnModeler.get('modeling')
					const businessObject = newVal.businessObject
					if (newVal.type == 'bpmn:UserTask' || newVal.type == 'bpmn:EndEvent') {
						// 默认给每个任务节点选中同意按钮
						this.btnGroup = businessObject.btnGroup ? JSON.parse(businessObject.btnGroup) : [{id: businessObject.id,modalKey: businessObject.$parent.id,nodeButtonCode: 'agree',nodeButtonName:'同意'}];

						this.buttonCodeList = this.btnGroup.map(e => e.nodeButtonCode)
						this.dialogEnableList = this.btnGroup.map((e) => {
							if (typeof e.dialog === "undefined") {
								e.dialog = {
									enable: false,
									pageUrl: "",
								};
							}

							return {
								nodeButtonCode: e.nodeButtonCode,
								nodeButtonName: e.nodeButtonName,
								dialog: e.dialog,
							};
						});
						this.loadButtonConfig();
						// if(this.$refs.table?.localDataSource){
						// 	this.$refs.table.localDataSource.forEach(item => {
						// 		item.enable = false
						// 	})
						// 	this.buttonCodeList.forEach(item => {
						// 		let index = this.$refs.table.localDataSource.map(e => e.buttonCode).indexOf(item);
						// 		if(index != -1){
						// 			this.$refs.table.localDataSource[index].enable = true
						// 		}
						// 	})
						// }
					}
					if (this.nodeElement.type == "bpmn:StartEvent") {
						this.updateName("开始");
					}
					if (this.nodeElement.type == "bpmn:EndEvent") {
						this.updateName("结束");
					}
					if (newVal.businessObject?.extensionElements) {
						// 执行监听器
						this.executionListener = newVal.businessObject.extensionElements?.values
							.filter(item => item.$type === 'flowable:ExecutionListener')
							.map(item => {
								let type
								if ('class' in item) type = 'class'
								if ('expression' in item) type = 'expression'
								if ('delegateExpression' in item) type = 'delegateExpression'
								return {
									event: item.event,
									type: type,
									className: item[type],
									params: item.fields?.map(field => {
										let fieldType
										if ('stringValue' in field) fieldType = 'stringValue'
										if ('expression' in field) fieldType = 'expression'
										return {
											name: field.name,
											type: fieldType,
											value: field[fieldType],
											editable: false
										}
									}) ?? []
								}
							}) ?? []
						// 任务监听器
						this.taskListener = businessObject.extensionElements?.values
							.filter(item => item.$type === 'flowable:TaskListener')
							.map(item => {
								let type
								if ('class' in item) type = 'class'
								if ('expression' in item) type = 'expression'
								if ('delegateExpression' in item) type = 'delegateExpression'
								return {
									event: item.event,
									type: type,
									className: item[type],
									params: item.fields?.map(field => {
										let fieldType
										if ('stringValue' in field) fieldType = 'stringValue'
										if ('expression' in field) fieldType = 'expression'
										return {
											name: field.name,
											type: fieldType,
											value: field[fieldType],
											editable: false
										}
									}) ?? []
								}
							}) ?? []
					}
				}
			},
			'formData.async': function(val) {
				if (val === '') val = null
				this.updateProperties({
					'flowable:async': val
				})
				this.$emit('setFormBtnData', 'async', val);
			},
			'formData.isForCompensation': function(val) {
				if (val === '') val = null
				this.updateProperties({
					'isForCompensation': val
				})
				this.$emit('setFormBtnData', 'isForCompensation', val);
			},
			'formData.ruleVariablesInput': function(val) {
				if (val === '') val = null
				this.updateProperties({
					'flowable:ruleVariablesInput': val
				})
				this.$emit('setFormBtnData', 'ruleVariablesInput', val);
			},
			'formData.rules': function(val) {
				if (val === '') val = null
				this.updateProperties({
					'flowable:rules': val
				})
				this.$emit('setFormBtnData', 'rules', val);
			},
			'formData.resultVariable': function(val) {
				if (val === '') val = null
				this.updateProperties({
					'flowable:resultVariable': val
				})
				this.$emit('setFormBtnData', 'resultVariable', val);
			},
			'formData.exclude': function(val) {
				if (val === '') val = null
				this.updateProperties({
					'flowable:exclude': val
				})
				this.$emit('setFormBtnData', 'exclude', val);
			},
			'formData.autoStoreVariables': function(val) {
				if (val === '') val = null
				this.updateProperties({
					'flowable:autoStoreVariables': val
				})
				this.$emit('setFormBtnData', 'autoStoreVariables', val);
			},
			'formData.triggerable': function(val) {
				if (val === '') val = null
				this.updateProperties({
					'flowable:triggerable': val
				})
				this.$emit('setFormBtnData', 'triggerable', val);
			},
			'formData.skipExpression': function(val) {
				if (val === '') val = null
				this.updateProperties({
					'flowable:skipExpression': val
				})
				this.$emit('setFormBtnData', 'skipExpression', val);
			},
			'formData.formModuleType': function(val) {
				if (val === '') val = null
				this.updateProperties({
					'formModuleType': val
				})
				this.$emit('setFormBtnData', 'formModuleType', val);
			},
			'formData.formEditable': function(val) {
				if (val === '') {
					val = null
				} else {
					val = Number(val)
				}
				this.updateProperties({
					'formEditable': val
				})
				this.$emit('setFormBtnData', 'formEditable', val);
				this.changeFormModuleBtn()
			}
		},
		methods: {
			//按钮
			changeFormModuleBtn() {
				let businessObject = this.nodeElement.businessObject
				let btnFormList = businessObject.btnGroup ? JSON.parse(businessObject.btnGroup) : [];
				let formBtnList = this.btnGroup.filter(obj => obj.id != businessObject.id)
				if (btnFormList.length === 0) {
					formBtnList.push({
						id: businessObject.id,
						modalKey: businessObject.$parent.id,
						nodeFormPath: businessObject.formDesignUrl,
						nodeFormEditPath: businessObject.formDesignDetailUrl,
						whetherUpdate: businessObject.formEditable,
						nodeFormUpdatePath: businessObject.nodeFormUpdatePathUrl,
						nodeFormSavePath: businessObject.nodeFormSavePathUrl,
					})
				} else {
					btnFormList.forEach(e => {
						e.id = businessObject.id,
							e.modalKey = businessObject.$parent.id
						e.nodeFormPath = businessObject.formDesignUrl
						e.nodeFormEditPath = businessObject.formDesignDetailUrl
						e.whetherUpdate = businessObject.formEditable
						e.nodeFormUpdatePath = businessObject.nodeFormUpdatePathUrl
						e.nodeFormSavePath = businessObject.nodeFormSavePathUrl,
							formBtnList.push(e)
					})
				}
				this.updateProperties({
					btnGroup: JSON.stringify(formBtnList)
				});
				this.$emit('setFormBtnData', 'btnGroup', formBtnList)
			},
			// 按钮配置
			openBtnPop() {
				this.btnPopups = true
				this.$refs.btnPopList.getBtnList(this.btnGroup)
			},
			// 按钮数据处理
			setBtnGroupItem(index, type) {
				let businessObject = this.nodeElement.businessObject
				if (type === 'list') {
					this.btnGroup = []
					index.forEach(e => {
						this.btnGroup.push({
							nodeButtonCode: e.buttonCode,
							nodeButtonName: e.buttonName,
							id: businessObject.id,
							modalKey: businessObject.$parent.id,
							nodeFormPath: businessObject.formDesignUrl,
							nodeFormEditPath: businessObject.formDesignDetailUrl,
							nodeFormUpdatePath: businessObject.nodeFormUpdatePathUrl,
							nodeFormSavePath: businessObject.nodeFormSavePathUrl,
							whetherUpdate: businessObject.formEditable
						})
					})
				} else if (index >= 0) {
					this.btnGroup.splice(index, 1)
				} else {
					if (!this.btnGroup) this.btnGroup = []
					this.btnGroup.push({
						nodeButtonCode: '',
						nodeButtonName: '',
						id: businessObject.id,
						modalKey: businessObject.$parent.id,
						nodeFormPath: businessObject.formDesignUrl,
						nodeFormEditPath: businessObject.formDesignDetailUrl,
						nodeFormUpdatePath: businessObject.nodeFormUpdatePathUrl,
						nodeFormSavePath: businessObject.nodeFormSavePathUrl,
						whetherUpdate: businessObject.formEditable
					})
				}
				this.updateProperties({
					btnGroup: JSON.stringify(this.btnGroup)
				});
				this.$emit('setFormBtnData', 'btnGroup', this.btnGroup)
			},
			updateProperties(properties) {
				this.modeler.get("modeling").updateProperties(this.nodeElement, properties);
			},
			updateName(name) {
				this.updateProperties({
					name: name
				});
			},
      switchChange(value, record, key){
				record[key] = value
				let businessObject = this.nodeElement.businessObject;

				if(value){
					this.btnGroup.push({
						nodeButtonCode: record.buttonCode,
						nodeButtonName: record.buttonName,
						id: businessObject.id,
						modalKey: businessObject.$parent.id,
						nodeFormPath: businessObject.formDesignUrl,
						nodeFormEditPath: businessObject.formDesignDetailUrl,
						nodeFormUpdatePath: businessObject.nodeFormUpdatePathUrl,
						nodeFormSavePath:businessObject.nodeFormSavePathUrl,
						whetherUpdate: businessObject.formEditable
					});
				}else{
					this.btnGroup.forEach((item, index) => {
						if(item.nodeButtonCode === record.buttonCode){
							this.btnGroup.splice(index, 1)
						}
					})
				}

				this.updateProperties({
				  btnGroup: JSON.stringify(this.btnGroup)
				});


      },
			switchDialogEnableChange(value, record, key) {
				record.dialog = { enable: value };
				this.btnGroup.forEach((item) => {
					if (item.nodeButtonCode === record.buttonCode) {
						item.dialog = { enable: value };
					}
				});
				// 更新按钮组
				this.updateProperties({
					btnGroup: JSON.stringify(this.btnGroup),
				});
			},
			openBtnConfigDialog(record) {
				const dialogEnableList = this.btnGroup;
				let dialogConfig = {
					dialog: {},
					nodeButtonCode: record.buttonCode,
					nodeButtonName: record.buttonName,
				}
				if(Array.isArray(dialogEnableList)) {
					const configItem = dialogEnableList.find(
						(item) => item.nodeButtonCode === record.buttonCode
					);
					configItem && (dialogConfig = configItem);
				}
				dialogConfig.dialog.buttonCode = record.buttonCode;
				this.$refs.buttonDialogConfigRef.openModal(dialogConfig);
			},
			btnConfigDialogHandleOk(e) {
				const btnModalConfig = e;
				const nodeButtonCode = btnModalConfig.nodeButtonCode;
				const groupItem = this.btnGroup.find(item => item.nodeButtonCode === nodeButtonCode);
				if (groupItem) {
					groupItem.dialog = {
						...btnModalConfig.dialog,
					};
				}
				this.updateProperties({
					btnGroup: JSON.stringify(this.btnGroup),
				});
			},
			btnConfigDialogHandleCancel() {
			},
			// 加载按钮配置
			loadButtonConfig() {
				if (!this.$refs.table?.localDataSource) return;
				const commonData = this.$refs.table.localDataSource || [];
				// 设置默认为false未选取状态
				// 普通按钮
				commonData.forEach((item) => {
					if (this.buttonCodeList.indexOf(item.buttonCode) > -1) {
						item.enable = true;
					} else {
						item.enable = false;
					}
					const dialogItem = this.dialogEnableList.find((dialogItem) => {
						return item.buttonCode === dialogItem.nodeButtonCode;
					});
					if (dialogItem && dialogItem.dialog?.enable) {
						item.dialog.enable = true;
					} else {
						item.dialog.enable = false;
					}
				});
			}
		}
	}
</script>

<style lang="less" scoped="scoped">
	.select-item {
	  display: flex;
	  align-items: center;
	  padding: 5px 10px;
	  .select-line-icon {
	    margin: 0 5px;
	  }
	}
</style>
